package com.ohs.bll.service.impl;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import com.ohs.bll.service.ScheduleService;
import com.ohs.bll.util.DateUtil;
import com.ohs.dal.dao.BookingDAO;
import com.ohs.dal.dao.LocationDAO;
import com.ohs.dal.dao.RoomDAO;
import com.ohs.dal.dao.ScheduleDAO;
import com.ohs.dal.model.Booking;
import com.ohs.dal.model.Location;
import com.ohs.dal.model.Room;
import com.ohs.dal.model.Schedule;
import com.ohs.dal.model.ScheduleId;

public class ScheduleServiceImpl implements ScheduleService {

	private ScheduleDAO scheduleDAO;
	
	private BookingDAO bookingDAO;
	
	private RoomDAO roomDAO;
	
	private LocationDAO locationDAO;

	public void add(Schedule Schedule) {
		scheduleDAO.add(Schedule);
	}
	
	public void update(Schedule Schedule) {
		scheduleDAO.update(Schedule);
	}

	public Schedule get(ScheduleId scheduleId) {
		return scheduleDAO.get(scheduleId);
	}

	public List<Schedule> findByRoom(long roomId) {
		return scheduleDAO.findByRoom(roomId);
	}
	
	public ScheduleDAO getScheduleDAO() {
		return scheduleDAO;
	}

	public void setScheduleDAO(ScheduleDAO scheduleDAO) {
		this.scheduleDAO = scheduleDAO;
	}

	public boolean isSetupSchedule(String username) {
		return scheduleDAO.isSetupSchedule(username);
	}

	public BookingDAO getBookingDAO() {
		return bookingDAO;
	}

	public void setBookingDAO(BookingDAO bookingDAO) {
		this.bookingDAO = bookingDAO;
	}

	public LocationDAO getLocationDAO() {
		return locationDAO;
	}

	public void setLocationDAO(LocationDAO locationDAO) {
		this.locationDAO = locationDAO;
	}

	public RoomDAO getRoomDAO() {
		return roomDAO;
	}

	public void setRoomDAO(RoomDAO roomDAO) {
		this.roomDAO = roomDAO;
	}

	public List<String> getAvailableTime(String username, ScheduleId scheduleId, String selectedDate) {
		Schedule schedule = scheduleDAO.get(scheduleId);
		Room room = roomDAO.get(scheduleId.getRoomId());
		List<String> availableTime = new ArrayList<String>();
		List<String> unavailableTime = new ArrayList<String>();
		Location location = locationDAO.getByAccount(username);
		if (schedule.getEnable()) {
			try {
				Date fromDate = DateUtil.stringToDate(selectedDate, "00:00");
				Date toDate = DateUtil.stringToDate(selectedDate, "23:59");
				List<Booking> bookings = bookingDAO.getBookingWithin(scheduleId.getRoomId(), fromDate, toDate);
				if (bookings != null && bookings.size() > 0) {
					for (Booking booking : bookings) {
						Date date = DateUtil.covertToStartOfDate(booking.getBookingDate());
						if (date.compareTo(DateUtil.stringToDate(selectedDate)) == 0) {
							unavailableTime.add(DateUtil.getTime(booking.getBookingDate()));
						}
					}
				}
				for (int i=schedule.getStartHour(); i <= schedule.getEndHour(); i++) {
	      		   int j = schedule.getStartMin();
	      		   if (i > schedule.getStartHour()) {
	      			   j = 0;
	      		   }
	      		   int end = schedule.getEndMin();
	      		   if (i < schedule.getEndHour()) {
	      			   end = 60;
	      		   }
	      		   for (; j < end; j+=room.getTimeslotInterval()) {
	      			   String timeFormat = formatTime(i) + ":" + formatTime(j);
	      			   String startTime = formatTime(schedule.getStartHour()) + ":" + formatTime(schedule.getStartMin());
	      			   if (isInAllowTime(fromDate, location.isAllowBookRightaway(), location.getAllowBookBefore(), timeFormat, startTime, room)) {
	      				   availableTime.add(timeFormat + " " + !unavailableTime.contains(timeFormat));
	      			   }
	      		   }
	      	   }
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}
		return availableTime;
	}

	private String formatTime(int number) {
		return (number < 10) ? "0" + number : number + "";	
	}
	
	private boolean isInAllowTime(Date startOfSelectedDate, boolean allowRightaway, int timeBefore, String timeSlot, String startTime, Room room) {
		// is in break time
		String[] split = timeSlot.split(":");
		int hour = Integer.parseInt(split[0]);
		int min = Integer.parseInt(split[1]);
		int timeInMin = hour*60 + min;
		int breakStart = room.getStartBreakHour()*60 + room.getStartBreakMin();
		int breakEnd = room.getEndBreakHour()*60 + room.getEndBreakMin();
		if (timeInMin >= breakStart  && timeInMin <= breakEnd ) {
			return false;
		}
			
		Date now = Calendar.getInstance().getTime();
		if (DateUtil.covertToStartOfDate(now).compareTo(startOfSelectedDate) > 0) {
			// booking for the past
			return false;
		} else if (DateUtil.covertToStartOfDate(now).compareTo(startOfSelectedDate) < 0) {
			// booking for the future
			return true;
		}
		String nowTime = DateUtil.getTime(now);
		if (allowRightaway) {
			return DateUtil.time1BeforeTime2(nowTime, timeSlot, timeBefore);
		} else {
			return DateUtil.time1BeforeTime2(nowTime, startTime, timeBefore);
		}
	}
}
